// 基础类型
const num: number = 10;
const str: string = 'hello';
const bool: boolean = true;
const nul: null = null; // 表示空值，只有null
const undef: undefined = undefined; // 表示未定义，只有undefined

const date: Date = new Date()

// 泛型
const arr: Array<number> = [1, 2, 3]; // 泛型数组方式1
const arr1: number[] = [1, 2, 3]; // 泛型数组方式2
const map: Map<string, number> = new Map() // map里面装基础类型的数据
const weakMap: WeakMap<object, number> = new WeakMap() // weakMap 引用类型的数据
const set: Set<number> = new Set()// set里面装基础类型的数据
const weakSet: WeakSet<object> = new WeakSet() // weakSet 引用类型的数据

// 元组类型，需要按照顺序定义好
const typeIds: [number, string] = [1, 'hello']

// 枚举
// 自增的枚举
enum TodoStatus {
    Pending, // 0
    InProgress, // 1
    Completed, // 2
}
const todoStatus: TodoStatus = TodoStatus.Pending;
// 赋值的枚举
enum Color {
    Red = 100,
    Green = 200,
    Blue = 300,
    Yellow,
}
const color: Color = Color.Yellow;
console.log(color) // 301
console.log(Color.Red) // 100

// any
let any: any = 10;
any = 'hello';
any = true;
console.log(any.toUpperCase()) // √ 可直接使用

// unknown
let unknown: unknown = 10;
unknown = 'hello';
unknown = true;
// console.log(unknown.toUpperCase()) // × 编辑器会报错
if (typeof unknown === 'string') { // √ 需要校验后才能使用
    console.log(unknown.toUpperCase())
}

// void: 表示 没有返回值 的函数的返回类型
function sayHello(): void {
    console.log('hello')
}

// never: 表示 永远不会有返回值 的函数的返回类型
function throwError(): never {
    throw new Error('error')
}

function fun(): never {
    while (true) {
        console.log('hello')
    }
}

// function loop(): never { // × 编辑器会报错
//     for (let i = 0; i < 10; i++) {
//         console.log('hello')
//     }
// }

function loopN(): never { // √
    for (; ;) {
        console.log('hello')
    }
}

// 断言：类型断言用于手动指定一个值的类型
// 方式一
const str1: string = 'hello';
const strLen1: number = (str1 as string).length;
// 方式二
const strLen2: number = (<string>str1).length;

// 联合类型: 表示一个值可以是几种类型之一，用 | 连接
let strOrNum: string | number = 'hello';
strOrNum = 10;

// 交叉类型： 表示多个类型的并集，用 & 连接
interface Rectangle {
    width: number;
    lenght: number;
}
interface Cal {
    perimeter: number;
    area: number;
}

type RectangleCal = Rectangle & Cal

const rect: RectangleCal = {
    width: 10,
    lenght: 20,
    perimeter: 60,
    area: 200,
}

type TodoId = number | string

// 自定义类型（类型的别名）
type Todo = {
    id: TodoId;
    title: string;
    completed: boolean;
}

const todo: Todo = {
    id: 1,
    title: 'hello',
    completed: true,
}

// 扩展类
class Computer {
    coding() {
        console.log('coding')
    }
}
class Phone {
    call() {
        console.log('call')
    }
}
type ComputerPhone = Computer & Phone

const computerPhone: ComputerPhone = {
    coding() {
        console.log('coding 电脑')

    },
    call() {
        console.log('call 手机')
    }
}

type Organism = {
    name: string;
    age: number;
}

type Person = Organism & {
    sex: string;
}

const person: Person = {
    name: '张三',
    age: 18,
    sex: '男',
}